window.onload = () => {
    const VSHADER_SOURCE = `
    attribute vec4 a_Position;
    void main(){
      gl_Position = a_Position;
      gl_PointSize=2.0;
    }`;

    const FSHADER_SOURCE = `
    precision mediump float;
    uniform vec4 u_FragColor;
    void main(){
      gl_FragColor = u_FragColor;
    }`;
    const canvas = document.getElementById('webgl');
    const gl = getWebGLContext(canvas);
    if (!gl) {
        console.log('Fail');
        return;
    }
    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
        console.log('Failed');
        return;
    }

    let a_Position = gl.getAttribLocation(gl.program, 'a_Position');
    let u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');

    const pointsTranslationPosition = (array, formerLineWidth) => {
        let lineWidth = formerLineWidth / 2;
        if (array.length < 1 || array.length % 2 !== 0) return;
        let newArray = [];
        let formerFlag = false;

        const triangleFan = (x1, y1, x2, y2, px, py) => {
            let newArrayTriangleFan = [];
            let [x1px, y1py, x2px, y2py] = [x1 - px, y1 - py, x2 - px, y2 - py];
            let radius = Math.sqrt((x1px * x1px + y1py * y1py));
            let angleL1 = Math.acos(x1px / radius);
            let averageAngle = Math.acos((x1px * x2px + y1py * y2py) / (radius * radius)) / 5;
            // console.log(angleL1);
            if (y1 - py < 0) {
                angleL1 = angleL1 > 0 ? -angleL1 : angleL1;
            }
            // // angleL1 %= Math.PI;
            newArrayTriangleFan.push(px);
            newArrayTriangleFan.push(py);
            newArrayTriangleFan.push(x1);
            newArrayTriangleFan.push(y1);
            // console.log(angleL1 * 180 / Math.PI, x1, y1, x2, y2, px, py);

            let [x3px, y3py] = [radius * Math.cos(angleL1 + averageAngle), radius * Math.sin(angleL1 + averageAngle)];
            // console.log(cos, sin);
            let tempAngle = Math.acos((x2px * x3px + y2py * y3py) / (radius * radius)) + Math.acos((x1px * x3px + y1py * y3py) / (radius * radius));
            if (Math.abs(tempAngle - averageAngle * 5) > 0.000001) {
                averageAngle = -averageAngle;
            }
            // console.log(Math.acos((x1px * x2px + y1py * y2py) / (radius * radius)) * 180 / Math.PI);
            for (let i = 1; i < 5; i++) {
                let [cos, sin] = [Math.cos(angleL1 + averageAngle * i), Math.sin(angleL1 + averageAngle * i)];
                console.log(px + radius * cos, py + radius * sin, x1px, Math.acos(x1px / radius) * 180 / Math.PI);
                newArrayTriangleFan.push(px + radius * cos);
                newArrayTriangleFan.push(py + radius * sin);
            }
            newArrayTriangleFan.push(x2);
            newArrayTriangleFan.push(y2);
            console.log(newArrayTriangleFan);
            return newArrayTriangleFan;
        };

        let newArrayTriangleFan = [];
        for (let i = 0,
            length = array.length; i < length; i = i + 2) {
            if (i === 0) {
                let [X1, Y1, X2, Y2] = [array[i], array[i + 1], array[i + 2], array[i + 3]];
                let temp = Math.sqrt((Y1 - Y2) * (Y1 - Y2) + (X1 - X2) * (X1 - X2));
                let x1 = (Y1 - Y2) * lineWidth / temp;
                let y1 = (X2 - X1) * lineWidth / temp;
                newArray.push(X1 - x1);
                newArray.push(Y1 - y1);
                newArray.push(x1 + X1);
                newArray.push(y1 + Y1);
            } else if (i === length - 2) {
                let [X1, Y1, X2, Y2] = [array[i - 2], array[i - 1], array[i], array[i + 1]];
                let temp = Math.sqrt((Y1 - Y2) * (Y1 - Y2) + (X1 - X2) * (X1 - X2));
                let x1 = (Y1 - Y2) * lineWidth / temp;
                let y1 = (X2 - X1) * lineWidth / temp;
                if (!formerFlag) {
                    newArray.push(X2 - x1);
                    newArray.push(Y2 - y1);
                    newArray.push(x1 + X2);
                    newArray.push(y1 + Y2);
                } else {
                    newArray.push(x1 + X2);
                    newArray.push(y1 + Y2);
                    newArray.push(X2 - x1);
                    newArray.push(Y2 - y1);
                }
            } else {
                let [X1, Y1, X2, Y2] = [array[i - 2], array[i - 1], array[i + 2], array[i + 3]];
                let [Xmiddle, Ymiddle] = [array[i], array[i + 1]];

                let lineLength1 = Math.sqrt((Xmiddle - X1) * (Xmiddle - X1) + (Ymiddle - Y1) * (Ymiddle - Y1));
                let lineLength2 = Math.sqrt((X2 - Xmiddle) * (X2 - Xmiddle) + (Y2 - Ymiddle) * (Y2 - Ymiddle)); // check linelength1/2 ===0

                let angle = Math.acos(((X1 - Xmiddle) * (X2 - Xmiddle) + (Y1 - Ymiddle) * (Y2 - Ymiddle)) /
                    (lineLength1 * lineLength2));
                let tempLineWidth = lineWidth / Math.sin(angle * 0.5);

                let [vectorX, vectorY] = [(Xmiddle - X1) / lineLength1 + (X2 - Xmiddle) / lineLength2,
                    (Ymiddle - Y1) / lineLength1 + (Y2 - Ymiddle) / lineLength2
                ];
                let [pX, pY] = [0, 0]; // 偏移量
                if (vectorX === 0 || vectorY === 0) {
                    if (vectorX === 0) {
                        if (vectorY > 0) {
                            pY = tempLineWidth;
                        } else if (vectorY < 0) {
                            pY = -tempLineWidth;
                        }
                    }
                    if (vectorY === 0) {
                        if (vectorX > 0) {
                            pX = tempLineWidth;
                        } else if (vectorY < 0) {
                            pX = -tempLineWidth;
                        }
                    }
                } else {
                    let temp = tempLineWidth / Math.sqrt(vectorX * vectorX + vectorY * vectorY);
                    pX = temp * vectorX;
                    pY = temp * vectorY;
                }
                let p1X = -pY + Xmiddle;
                let p1Y = pX + Ymiddle;
                let flag = true;
                if (-vectorY * (X2 - Xmiddle) + vectorX * (Y2 - Ymiddle) < 0) { // obtuse angle
                    flag = false;
                }
                // let [formerVectorXr, formerVectorYr] = [0, 0];
                if (flag) { // 切自己
                    let [xl, yl] = [0, 0];
                    if (formerFlag === false) {
                        xl = -newArray[newArray.length - 2] + p1X + X1;
                        yl = -newArray[newArray.length - 1] + p1Y + Y1;
                    } else if (formerFlag === true) {
                        xl = -newArray[newArray.length - 4] + p1X + 0.5 * (newArray[newArray.length - 2] + newArray[newArray.length - 4]);
                        yl = -newArray[newArray.length - 3] + p1Y + 0.5 * (newArray[newArray.length - 1] + newArray[newArray.length - 3]);
                        newArray.push((p1X + newArray[newArray.length - 4]) / 2);
                        newArray.push((p1Y + newArray[newArray.length - 4]) / 2);
                    }
                    let b = 0;
                    let k = 0;
                    let [xr, yr] = [0, 0];
                    if (pX !== 0) {
                        k = (p1Y - Ymiddle) / (p1X - Xmiddle);
                        b = p1Y - k * p1X;
                        xr = (2 * k * yl + (1 - k * k) * xl - 2 * k * b) / (k * k + 1);
                        yr = yl + (xl - xr) / k;
                    }
                    let [xl1, yl1, xr1, yr1] = [2 * xl - p1X, 2 * yl - p1Y, 2 * xr - p1X, 2 * yr - p1Y];
                    newArray.push(xl1);
                    newArray.push(yl1);
                    newArray.push(p1X);
                    newArray.push(p1Y);
                    newArray.push(xr1);
                    newArray.push(yr1);

                    newArrayTriangleFan = newArrayTriangleFan.concat(triangleFan(xl1, yl1, xr1, yr1, p1X, p1Y));

                } else {
                    let [xl, yl] = [0, 0];
                    if (formerFlag === false) {
                        xl = newArray[newArray.length - 2] + Xmiddle - X1;
                        yl = newArray[newArray.length - 1] + Ymiddle - Y1;
                        newArray.push(((Xmiddle + pY) + newArray[newArray.length - 4]) / 2);
                        newArray.push(((Ymiddle - pX) + newArray[newArray.length - 4]) / 2);
                    } else if (formerFlag === true) {
                        // xl = -newArray[newArray.length - 2] + (Xmiddle + pY) + newArray[newArray.length - 4];
                        // yl = -newArray[newArray.length - 1] + (Ymiddle - pX) + newArray[newArray.length - 3];
                        xl = (newArray[newArray.length - 4] - newArray[newArray.length - 2]) * 0.5 + Xmiddle;
                        yl = (newArray[newArray.length - 3] - newArray[newArray.length - 1]) * 0.5 + Ymiddle;
                    }
                    let b = 0;
                    let k = 0;
                    let [xr, yr] = [0, 0];
                    if (pX !== 0) {
                        k = (p1Y - Ymiddle) / (p1X - Xmiddle);
                        b = p1Y - k * p1X;
                        xr = (2 * k * yl + (1 - k * k) * xl - 2 * k * b) / (k * k + 1);
                        yr = yl + (xl - xr) / k;
                    }

                    newArray.push(xl);
                    newArray.push(yl);
                    newArray.push(Xmiddle + pY);
                    newArray.push(Ymiddle - pX);
                    newArray.push(xr);
                    newArray.push(yr);
                    newArrayTriangleFan = newArrayTriangleFan.concat(triangleFan(xl, yl, xr, yr, Xmiddle + pY, Ymiddle - pX));
                }
                formerFlag = flag;
            }
        }
        return {
            'newArray': newArray,
            'newArrayTriangleFan': newArrayTriangleFan
        };
    };

    let data = [
    ];
    /**
     * 0.0, 0.5,
        0.0, 0.0,
        0.3, -0.3,
        0.3, -0.5,
        0.5, -0.6,
        0.9, 0.8
     */
    for (let i = 0; i < 10; i++) {
        if (Math.random() < 0.5) {
            data.push((-1) * Math.random());
        } else {
            data.push(Math.random());
        }
    }
    let dataObj = pointsTranslationPosition(data, 20 / 200);
    let newData = dataObj.newArray;
    let vertices = new Float32Array(newData.concat(dataObj.newArrayTriangleFan));
    let length = newData.length;
    let vertexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(a_Position);

    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    console.log(data, vertices, dataObj.newArrayTriangleFan);
    gl.uniform4f(u_FragColor, ...[0.0, 1.0, 0.0, 1.0]);
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, length / 2); // TRIANGLE_STRIP  LINE_STRIP POINTS
    // gl.uniform4f(u_FragColor, ...[1.0, 0.0, 0.0, 1.0]);
    for (let i = length / 2; i < vertices.length / 2; i += 7) {
        console.log((vertices.length - length) / 14);
        gl.drawArrays(gl.TRIANGLE_FAN, i, 7);
    }
    // gl.drawArrays(gl.TRIANGLE_FAN, length / 2, (vertices.length - length) / 2);
    // gl.uniform4f(u_FragColor, ...[1.0, 0.0, 0.0, 1.0]);
    // gl.drawArrays(gl.LINE_STRIP, 0, (length) / 2);
    // gl.uniform4f(u_FragColor, ...[1.0, 1.0, 1.0, 1.0]);
    // gl.drawArrays(gl.POINTS, 0, length / 2);
};